package org.daochong.fastdev;

import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.Map;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

import org.daochong.lang.BeanUtil;
import org.daochong.lang.JdbcTemplate;
import org.daochong.lang.JdbcTemplateProvider;
import org.daochong.lang.Properties;
import org.daochong.lang.StringUtils;
import org.daochong.lang.ucm.Configuration;
import org.daochong.lang.ucm.ConfigurationContainer;

public class ClassMappingFactory implements IClassMappingFactory {

	private String groupId = "JdbcClassMapping";

	private ConfigurationContainer container;

	private JdbcTemplateProvider jdbcTemplateProvider;

	public JdbcTemplateProvider getJdbcTemplateProvider() {
		return jdbcTemplateProvider;
	}

	public void setJdbcTemplateProvider(JdbcTemplateProvider jdbcTemplateProvider) {
		this.jdbcTemplateProvider = jdbcTemplateProvider;
	}

	public String getGroupId() {
		return groupId;
	}

	public void setGroupId(String groupId) {
		this.groupId = groupId;
	}

	public ConfigurationContainer getContainer() {
		return container;
	}

	public void setContainer(ConfigurationContainer container) {
		this.container = container;
	}

	public Class<?> getEntity(String entity) {
		List<Configuration> list = this.container.getConfigurations(getGroupId());
		for (Configuration cfg : list) {
			Properties p = cfg.getProperties();
			if (p == null)
				continue;
			if (p.getProperty(entity) != null) {
				String clsString = p.getProperty(entity);
				return getClass(clsString);
			}
		}
		return null;
	}

	private Class<?> getClass(String cls) {
		int pos = cls.indexOf(":");
		String table = null;
		if (pos > 0) {
			table = cls.substring(pos + 1);
			cls = cls.substring(0, pos);
		}
		try {
			return Class.forName(cls);
		} catch (ClassNotFoundException e) {
			if (this.getJdbcTemplateProvider() != null) {
				JdbcTemplate jdbc = this.getJdbcTemplateProvider().requestJdbcTempalte();
				pos = cls.lastIndexOf('.');
				String packageName = "";
				String className = cls;
				if (pos > 0) {
					packageName = cls.substring(0, pos);
					className = cls.substring(pos + 1);
				}
				if (StringUtils.isEmpty(table)) {
					throw new RuntimeException(e);
				} else {
					try {
						String path = System.getProperty("user.dir") + "/src/main/java";
						if (new File(path).exists()) {
							jdbc.createBeanCode(table, packageName, className, path);
						}
						path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
						jdbc.createBeanCode(table, packageName, className, path);
						JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
						URL url = javax.persistence.Id.class.getProtectionDomain().getCodeSource().getLocation();
						compiler.run(null, System.out, System.err, "-d", path, "-cp", url.getFile(),
								path + "/" + cls.replaceAll("\\.", "/") + ".java");
						Thread.sleep(200);
						return Class.forName(cls);
					} catch (Exception ex) {
						ex.printStackTrace();
						throw new RuntimeException(e);
					}
				}
			}
			throw new RuntimeException(e);
		}
	}

	public Object getEntity(String entity, Map<String, Object> params) {
		Class<?> clazz = getEntity(entity);
		if (clazz != null && params != null) {
			return BeanUtil.pushBean(params, clazz);
		}
		return null;
	}

}
